package com.vehiclesecure.service;

import com.vehiclesecure.crypto.EncryptionService;
import com.vehiclesecure.model.User;
import com.vehiclesecure.model.Vehicle;
import com.vehiclesecure.model.VehicleData;
import com.vehiclesecure.repository.VehicleDataRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * 车辆数据服务层，处理车辆数据的业务逻辑
 */
@Service
public class VehicleDataService {
    
    private final VehicleDataRepository vehicleDataRepository;
    private final EncryptionService encryptionService;
    private final VehicleService vehicleService;
    
    @Autowired
    public VehicleDataService(VehicleDataRepository vehicleDataRepository, 
                            EncryptionService encryptionService, 
                            VehicleService vehicleService) {
        this.vehicleDataRepository = vehicleDataRepository;
        this.encryptionService = encryptionService;
        this.vehicleService = vehicleService;
    }
    
    /**
     * 保存车辆数据，包括加密敏感信息
     * @param vehicleData 车辆数据对象
     * @return 保存后的车辆数据
     */
    public VehicleData saveVehicleData(VehicleData vehicleData) {
        // 为新数据设置时间戳
        if (vehicleData.getTimestamp() == null) {
            vehicleData.setTimestamp(LocalDateTime.now());
        }
        
        // 加密敏感数据
        if (vehicleData.getVehiclePlate() != null) {
            String sensitiveInfo = String.format("Plate:%s,Location:%s,%s",
                    vehicleData.getVehiclePlate(),
                    vehicleData.getLatitude(),
                    vehicleData.getLongitude());
            vehicleData.setEncryptedData(encryptionService.encrypt(sensitiveInfo));
        }
        
        // 生成设备签名（简化实现）
        vehicleData.setDeviceSignature(generateDeviceSignature(vehicleData.getVehicleId()));
        
        return vehicleDataRepository.save(vehicleData);
    }
    
    /**
     * 获取指定车辆的所有数据
     * @param vehicleId 车辆唯一标识符
     * @return 车辆数据列表
     */
    public List<VehicleData> getVehicleDataByVehicleId(String vehicleId) {
        return vehicleDataRepository.findByVehicleId(vehicleId);
    }
    
    /**
     * 获取当前用户有权访问的所有车辆数据
     * @param user 当前登录用户
     * @return 用户有权访问的车辆数据列表
     */
    public List<VehicleData> getUserAccessibleVehicleData(User user) {
        if (user == null || user.getVehicleIds() == null || user.getVehicleIds().isEmpty()) {
            return List.of();
        }
        
        // 对于普通用户，只返回其有权访问的车辆数据
        if (!user.getRole().equals(User.Role.ADMIN)) {
            // 分别查询每辆车的数据并合并
            return user.getVehicleIds().stream()
                    .flatMap(vehicleId -> vehicleDataRepository.findByVehicleId(vehicleId).stream())
                    .sorted((d1, d2) -> d2.getTimestamp().compareTo(d1.getTimestamp())) // 按时间倒序
                    .collect(Collectors.toList());
        }
        
        // 管理员可以查看所有数据
        return vehicleDataRepository.findAll();
    }
    
    /**
     * 获取所有车辆数据（用于服务商角色）
     * @return 所有车辆数据列表
     */
    public List<VehicleData> getAllVehicleData() {
        return vehicleDataRepository.findAll();
    }
    
    /**
     * 检查用户是否有权访问指定车辆
     * @param user 当前登录用户
     * @param vehicleId 车辆ID
     * @return 是否有权访问
     */
    public boolean hasAccessToVehicle(User user, String vehicleId) {
        // 管理员可以访问所有车辆
        if (user != null && user.getRole().equals(User.Role.ADMIN)) {
            return true;
        }
        
        // 如果用户为null，直接返回false
        if (user == null) {
            return false;
        }
        
        try {
            // 尝试获取车辆信息，使用orElseThrow处理Optional类型
            Vehicle vehicle = vehicleService.getVehicleById(vehicleId)
                .orElseThrow(() -> new RuntimeException("车辆不存在: " + vehicleId));
            
            // 检查用户是否是车辆所有者
            if (user.getId().equals(vehicle.getOwnerId())) {
                return true;
            }
            
            // 检查用户是否在授权用户列表中
            if (vehicle.getAuthorizedUsers() != null && 
                vehicle.getAuthorizedUsers().contains(user.getId())) {
                return true;
            }
            
            // 保留原有的检查逻辑（用户vehicleIds列表）
            if (user.getVehicleIds() != null && user.getVehicleIds().contains(vehicleId)) {
                return true;
            }
        } catch (Exception e) {
            // 如果获取车辆信息失败，则使用原有的检查逻辑
            if (user.getVehicleIds() != null && user.getVehicleIds().contains(vehicleId)) {
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * 获取指定车辆在时间范围内的数据
     * @param vehicleId 车辆唯一标识符
     * @param start 开始时间
     * @param end 结束时间
     * @return 车辆数据列表
     */
    public List<VehicleData> getVehicleDataByVehicleIdAndTimeRange(String vehicleId, LocalDateTime start, LocalDateTime end) {
        return vehicleDataRepository.findByVehicleIdAndTimestampBetween(vehicleId, start, end);
    }
    
    /**
     * 获取所有紧急情况数据
     * @return 紧急情况数据列表
     */
    public List<VehicleData> getEmergencyVehicleData() {
        return vehicleDataRepository.findByEmergencyFlagTrue();
    }
    
    /**
     * 根据ID获取车辆数据
     * @param id 数据ID
     * @return 车辆数据对象
     */
    public Optional<VehicleData> getVehicleDataById(String id) {
        return vehicleDataRepository.findById(id);
    }
    
    /**
     * 获取交通流量统计数据
     * @return 交通流量统计信息
     */
    public TrafficStats getTrafficStats() {
        List<VehicleData> allData = vehicleDataRepository.findAll();
        
        int totalVehicles = (int) allData.stream()
                .map(VehicleData::getVehicleId)
                .distinct()
                .count();
        
        int activeVehicles = (int) allData.stream()
                .filter(data -> data.getEngineStatus() == 1)
                .map(VehicleData::getVehicleId)
                .distinct()
                .count();
        
        double avgSpeed = allData.stream()
                .mapToInt(VehicleData::getSpeed)
                .average()
                .orElse(0.0);
        
        int highTrafficAreas = (int) allData.stream()
                .filter(data -> data.getSpeed() < 20 && data.getSpeed() > 0)
                .count();
        
        return new TrafficStats(totalVehicles, activeVehicles, Math.round(avgSpeed * 100.0) / 100.0, highTrafficAreas);
    }
    
    /**
     * 获取停车数据分析
     * @return 停车数据分析
     */
    public ParkingStats getParkingStats() {
        List<VehicleData> allData = vehicleDataRepository.findAll();
        
        int totalParked = (int) allData.stream()
                .filter(data -> data.getSpeed() == 0 && data.getEngineStatus() == 0)
                .map(VehicleData::getVehicleId)
                .distinct()
                .count();
        
        int potentiallyIllegal = (int) allData.stream()
                .filter(data -> data.getSpeed() == 0 && data.getEngineStatus() == 0)
                .filter(data -> data.getLatitude() < 39.9 || data.getLatitude() > 39.95)
                .map(VehicleData::getVehicleId)
                .distinct()
                .count();
        
        int availableSpots = Math.max(100 - totalParked, 0); // 假设总共有100个停车位
        
        return new ParkingStats(totalParked, potentiallyIllegal, availableSpots);
    }
    
    /**
     * 生成设备签名
     * @param vehicleId 车辆唯一标识符
     * @return 设备签名字符串
     */
    private String generateDeviceSignature(String vehicleId) {
        // 实际应用中应该使用更安全的签名算法
        return UUID.nameUUIDFromBytes((vehicleId + LocalDateTime.now().toString()).getBytes()).toString();
    }
    
    /**
     * 交通流量统计类
     */
    public static class TrafficStats {
        private final int totalVehicles;
        private final int activeVehicles;
        private final double avgSpeed;
        private final int highTrafficAreas;
        
        public TrafficStats(int totalVehicles, int activeVehicles, double avgSpeed, int highTrafficAreas) {
            this.totalVehicles = totalVehicles;
            this.activeVehicles = activeVehicles;
            this.avgSpeed = avgSpeed;
            this.highTrafficAreas = highTrafficAreas;
        }
        
        public int getTotalVehicles() { return totalVehicles; }
        public int getActiveVehicles() { return activeVehicles; }
        public double getAvgSpeed() { return avgSpeed; }
        public int getHighTrafficAreas() { return highTrafficAreas; }
    }
    
    /**
     * 停车数据统计类
     */
    public static class ParkingStats {
        private final int totalParked;
        private final int potentiallyIllegal;
        private final int availableSpots;
        
        public ParkingStats(int totalParked, int potentiallyIllegal, int availableSpots) {
            this.totalParked = totalParked;
            this.potentiallyIllegal = potentiallyIllegal;
            this.availableSpots = availableSpots;
        }
        
        public int getTotalParked() { return totalParked; }
        public int getPotentiallyIllegal() { return potentiallyIllegal; }
        public int getAvailableSpots() { return availableSpots; }
    }
}